package com.theorydance.esoperator;

import java.util.ArrayList;
import java.util.List;

import org.junit.Test;

import com.theorydance.esoperator.utils.Tools;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

/**
 * 根据指定的经纬度，在目标集合中查询最近的一个站点
 */
public class QueryStationByLngLat {

	/**
	 * 测试java计算能力，5000左右的计算，1毫秒
	 */
	@Test
	public void testCalc() {
		long current = System.currentTimeMillis();
		String content = Tools.readText("d:/tmp/sys_station.csv");
		System.out.println("读取文本内容，耗时：" + (System.currentTimeMillis() - current) + "ms");
		current = System.currentTimeMillis();
		String[] array = content.split("\\n");
		List<Point> pointList = new ArrayList<>();
		
		for (String line : array) {
			String arr[] = line.split(",");
			String siteId = arr[0];
			double lng = Tools.objTodouble(arr[1]);
			double lat = Tools.objTodouble(arr[2]);
			if(lng>0 && lat>0) {
				Point point = new Point(siteId, lng, lat);
				pointList.add(point);
			}
		}
		System.out.println("将读取的文本内容，转为Point对象集合，耗时：" + (System.currentTimeMillis() - current) + "ms");
		current = System.currentTimeMillis();
		System.out.println("list.size()=" + pointList.size());
		
		// 根据指定的经纬度，查询用时
		List<Point> targetList = new ArrayList<>();
		targetList.add(new Point("1", 116.42, 39.93));
		targetList.add(new Point("2", 116.37, 39.92));
		targetList.add(new Point("3", 106.33, 29.35));
		targetList.add(new Point("4", 116.92, 38.93));
		targetList.add(new Point("5", 110.349228, 20.017377));
		targetList.add(new Point("6", 131.08, 35.16));
		targetList.add(new Point("7", 113.826063, 34.022956));
		targetList.add(new Point("8", 104.06, 30.67));
		targetList.add(new Point("9", 104.741722, 31.46402));
		System.out.println("创建目标集合targetList，耗时：" + (System.currentTimeMillis() - current) + "ms");
		
		for (Point point : targetList) {
			current = System.currentTimeMillis();
			Point nearestPoint = getNearest(point, pointList);
			System.out.println("查找目标" + point.siteId + "，耗时：" + (System.currentTimeMillis() - current) + "ms, 最近站点信息： " + nearestPoint.toString());
		}
	}
	
	static Point getNearest(Point target, List<Point> pointList) {
		Double minDistance = 100000D;
		Point minPoint = null;
		for (Point point : pointList) {
			if(minPoint == null) {
				minPoint = point;
				continue;
			}
			double distance = Math.sqrt(Math.pow(point.lng - target.lng, 2) + Math.pow(point.lat - target.lat, 2));
			if(distance < minDistance) {
				minDistance = distance;
				minPoint = point;
			}
		}
		minPoint.setDistance(minDistance);
		return minPoint;
	}

	@ToString
	@Getter
	@Setter
	static class Point{
		String siteId;
		double lng;
		double lat;
		double distance;
		public Point(String siteId,double lng,double lat) {
			this.siteId = siteId;
			this.lng = lng;
			this.lat = lat;
		}
	}
}
